//代码实现线程间交替打印
//线程同步->保证访问资源的合理性
//线程互斥->保证访问资源的线程安全
#include<iostream>
#include<unistd.h>
#include<pthread.h>
using namespace std;
//用于等待对方的条件变量
pthread_cond_t cond_a=PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_b=PTHREAD_COND_INITIALIZER;
//用于穿行打印的互斥锁
pthread_mutex_t mutex_g=PTHREAD_MUTEX_INITIALIZER;
//用于穿行访问是否继续运行的互斥锁
pthread_mutex_t mutex_r=PTHREAD_MUTEX_INITIALIZER;
//用于等待对方的条件
volatile bool is_a_printed {true};
//用于检测是否继续运行的条件
volatile bool run {true};
//线程a的执行逻辑
void* thread_a_routine(void*argc){
    //run 标准输出 is_a_printed 都是临界资源,都必须穿行访问,分别被mutex_r,mutex_g保护.
    while(run){
        pthread_mutex_unlock(&mutex_r);
        pthread_mutex_lock(&mutex_g);
        //只要条件不满足就等待被唤醒
        while(is_a_printed){//while提高代码健壮性
            pthread_cond_wait(&cond_b,&mutex_g);
        }
        cout<<"我是线程A :> 我的用户级id:> "<<pthread_self()<<endl;
        cout.flush();
        //修改条件,代表a已经打印完毕
        is_a_printed=true;
        pthread_mutex_unlock(&mutex_g);
        pthread_cond_signal(&cond_a);
        //保证run的数据一致性,才能保证程序执行逻辑.
        pthread_mutex_lock(&mutex_r);
    }
    //一定保证每条路径正确解锁,避免死锁问题.
    pthread_mutex_unlock(&mutex_r);
}
//线程b的执行逻辑,与a一致
void*thread_b_routine(void*argc){
    while(run){
        pthread_mutex_unlock(&mutex_r);
        pthread_mutex_lock(&mutex_g);
        while(!is_a_printed){
            pthread_cond_wait(&cond_a,&mutex_g);
        }
        cout<<"我是线程B :> 我的用户级id:> "<<pthread_self()<<endl;
        cout.flush();
        is_a_printed=false;
        pthread_mutex_unlock(&mutex_g);
        pthread_cond_signal(&cond_b);
        pthread_mutex_lock(&mutex_r);
    }
    pthread_mutex_unlock(&mutex_r);

}
int main(){
    //创建线程
    pthread_t thread_a,thread_b;
    pthread_create(&thread_a,nullptr,thread_a_routine,nullptr);
    pthread_create(&thread_b,nullptr,thread_b_routine,nullptr);
    //观察结果
    sleep(5);
    //让线程退出
    run=false;
    //回收线程资源
    pthread_join(thread_a,nullptr);
    pthread_join(thread_b,nullptr);
    return 0;
}